Skip to content

Add CommandService/RequestFastUpdates and system diagnostics view - #23

Merged
eman merged 3 commits into
mainfrom
feat/command-service-and-diagnostics
Aug 3, 2026
Merged

Add CommandService/RequestFastUpdates and system diagnostics view#23
eman merged 3 commits into
mainfrom
feat/command-service-and-diagnostics

Conversation

@eman

@eman eman commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Two additions surfaced from reverse-engineering com.quilt.android versionCode 255. Reviewable commit-by-commit.

1. CommandService/RequestFastUpdates

A new service in the home_datastore package (cloud stub only — no local endpoint).

  • Adds CommandService + RequestFastUpdatesRequest + FastUpdateReason to the proto and regenerates stubs.
  • QuiltClient.request_fast_updates(reason=..., system_id=...) — asks the cloud to raise a system's telemetry cadence, the same lever the mobile app pulls on user activity or a degraded local mesh.
  • FastUpdateReason enum: UNSPECIFIED / LOCAL_COMMS_UNHEALTHY / USER_ACTIVITY.
  • Verified reachable against production (returns Empty, request accepted).

2. Diagnostics view

Surfaces the installer-style diagnostic picture from data the cloud API already returns — on the indoor units.

  • QuiltClient.get_diagnostics() / SystemSnapshot.diagnostics() → new SystemDiagnostics.
  • Per-IDU: fault/condition matrix (incl. ODU/refrigerant conditions surfaced through each IDU — outdoor_unit_communication_error, defrost_cycle, oil_return, …), refrigerant-circuit temps (coil / gas-pipe / liquid-pipe / inlet / outlet), humidity, and power.
  • New models IndoorUnitDiagnostics, OutdoorUnitDiagnostics, SystemDiagnostics; IndoorUnitConditions.active / .states() helpers.
  • New CLI command quilt diagnostics (--faults-only, --output json).
  • The outdoor unit's own raw board sensors (compressor Hz, pressures, discharge temp) are withheld from the cloud plane; OutdoorUnitDiagnostics.raw_sensors_available is False and this is flagged rather than faked.

Testing

ruff check · ruff format · mypy (46 files) · pytest (293 passed, 89% coverage; new diagnostics.py and command.py at 100%) · check_docs_nav · mkdocs build --strict — all green. Docs updated: client.md, models.md, grpc-services-matrix.md, cli-scripting.md, CHANGELOG.

Note: uv.lock

Second commit gitignores uv.lock. It isn't consumed by CI (which resolves from pyproject.toml), this is a published library (consumers never use the lock), and the tracked-but-untracked copy had already drifted out of sync. If dev/CI later standardize on uv sync --locked, commit it then and wire CI to it.

eman added 2 commits August 3, 2026 10:44
Two additions surfaced from reverse-engineering com.quilt.android 255.

CommandService / RequestFastUpdates
- New core.protos.home_datastore.CommandService with RequestFastUpdates,
  wrapped by QuiltClient.request_fast_updates(reason=..., system_id=...). Asks
  the cloud to raise a system's telemetry cadence — the lever the mobile app
  pulls on user activity or a degraded local mesh. New FastUpdateReason enum
  (UNSPECIFIED / LOCAL_COMMS_UNHEALTHY / USER_ACTIVITY). Verified reachable
  against production.

Diagnostics view
- QuiltClient.get_diagnostics() and SystemSnapshot.diagnostics() return a new
  SystemDiagnostics: the per-indoor-unit fault/condition matrix (including the
  outdoor-unit / refrigerant conditions surfaced through each IDU),
  refrigerant-circuit temperatures, and per-unit power. New
  IndoorUnitDiagnostics / OutdoorUnitDiagnostics models and
  IndoorUnitConditions.active / .states() helpers. New `quilt diagnostics` CLI
  command (--faults-only, --output json). The outdoor unit's own raw board
  sensors are withheld from the cloud plane and are flagged as such rather than
  reported.

Tests, reference docs, and CHANGELOG updated.
ruff / mypy / pytest (89% cov) / mkdocs --strict all green.
Not consumed by CI (which resolves from pyproject.toml) and this is a published
library, so consumers never use the lockfile. Keeps a dev-only, already-drifting
lock out of version control.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Not ready to approve

IndoorUnitConditions.states() can raise ValueError on unknown proto enum integers, which would break diagnostics assembly and the CLI at runtime.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

This PR extends the async Quilt client library with (1) a new cloud-only CommandService/RequestFastUpdates RPC wrapper to request higher telemetry cadence, and (2) an “installer-style” diagnostics view derived from snapshot data (plus a new quilt diagnostics CLI command), with accompanying proto/stub regeneration, tests, and documentation updates.

Changes:

  • Add CommandService.request_fast_updates() and QuiltClient.request_fast_updates() backed by new proto types (RequestFastUpdatesRequest, FastUpdateReason).
  • Add snapshot-derived diagnostics models (SystemDiagnostics, IndoorUnitDiagnostics, OutdoorUnitDiagnostics), SystemSnapshot.diagnostics(), and QuiltClient.get_diagnostics().
  • Add a quilt diagnostics CLI command, tests for both features, and update reference/docs/changelog.
File summaries
File Description
tests/test_diagnostics.py Adds coverage for condition helpers, diagnostics aggregation, client wrapper, and CLI output modes.
tests/test_command.py Adds coverage for RequestFastUpdates request construction, error translation, and client wrapper behavior.
src/quilt_hp/services/command.py Introduces a service wrapper around the generated CommandServiceStub for RequestFastUpdates.
src/quilt_hp/models/system.py Adds SystemSnapshot.diagnostics() to assemble a SystemDiagnostics view from a snapshot.
src/quilt_hp/models/indoor_unit.py Adds IndoorUnitConditions.FIELD_NAMES plus active/states() helpers and refactors any_active.
src/quilt_hp/models/enums.py Adds the public FastUpdateReason IntEnum.
src/quilt_hp/models/diagnostics.py Adds new diagnostics dataclasses and constructors (from_indoor_unit, from_outdoor_unit).
src/quilt_hp/models/init.py Re-exports new diagnostics models, FastUpdateReason, and IndoorUnitConditions.
src/quilt_hp/client.py Wires in CommandService, adds get_diagnostics(), and adds request_fast_updates().
src/quilt_hp/cli/main.py Adds quilt diagnostics command and formatting helpers; supports summary and JSON output.
src/quilt_hp/_proto/quilt_hds_pb2.pyi Regenerated type stubs to include FastUpdateReason and RequestFastUpdatesRequest.
src/quilt_hp/_proto/quilt_hds_pb2.py Regenerated protobuf module to include new enum/message/service descriptors.
src/quilt_hp/_proto/quilt_hds_pb2_grpc.py Regenerated gRPC stubs to include CommandServiceStub and server helpers.
proto/cleaned/quilt_hds.proto Adds FastUpdateReason, RequestFastUpdatesRequest, and CommandService to the cleaned proto source.
docs/reference/models.md Documents CommandService and the new diagnostics models/enums.
docs/reference/grpc-services-matrix.md Documents the new CommandService/RequestFastUpdates RPC mapping.
docs/reference/client.md Documents get_diagnostics() and request_fast_updates() public client APIs.
docs/how-to/cli-scripting.md Adds CLI scripting examples for the new diagnostics command.
CHANGELOG.md Adds unreleased entries describing both new features and their scope/limitations.
.gitignore Ignores uv.lock with rationale comment.
Review details

Files not reviewed (1)

  • src/quilt_hp/_proto/quilt_hds_pb2.py: Generated file
  • Files reviewed: 18/20 changed files
  • Comments generated: 1
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

Comment thread src/quilt_hp/models/indoor_unit.py Outdated
Comment on lines +210 to +212
def states(self) -> dict[str, ConditionState]:
"""Every condition mapped to its :class:`ConditionState`."""
return {name: ConditionState(getattr(self, name)) for name in self.FIELD_NAMES}

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — fixed in 42a19ec. IndoorUnitConditions.states() now routes each value through a _safe_condition_state() helper that falls back to UNSPECIFIED on unknown wire integers, matching the defensive pattern used for OutdoorUnit.hvac_state. (.active/.any_active were already safe — they compare raw ints and never construct the enum.) Added a regression test (test_conditions_tolerates_unknown_wire_value).

proto3 preserves unknown enum integers, so ConditionState(value) could raise
ValueError and break diagnostics()/the CLI if the backend adds a new condition
state. states() now falls back to UNSPECIFIED for unknown values, matching the
defensive pattern used for OutdoorUnit.hvac_state. (.active was already safe —
it compares raw ints.) Addresses Copilot review feedback.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Ready to approve

The changes are cohesive, well-tested, and align with existing service/model/client layering without introducing verified defects in the modified regions.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Review details

Files not reviewed (1)

  • src/quilt_hp/_proto/quilt_hds_pb2.py: Generated file
  • Files reviewed: 18/20 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

@eman
eman merged commit 2cc38a4 into main Aug 3, 2026
6 checks passed
@eman
eman deleted the feat/command-service-and-diagnostics branch August 3, 2026 18:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants